/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved.
 */

package com.device.idea.demo.view;

import static com.device.idea.demo.constant.Constant.BOARD_ID_KEY;
import static com.device.idea.demo.constant.Constant.ERR_CODE_KEY;
import static com.device.idea.demo.constant.Constant.ERR_MSG_KEY;
import static com.device.idea.demo.constant.Constant.IMAGE_SAVE_HEIGHT;
import static com.device.idea.demo.constant.Constant.IMAGE_SAVE_WIDTH;
import static com.device.idea.demo.constant.Constant.PAGE_NUMBER_KEY;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Point;
import android.graphics.Rect;
import android.net.Uri;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.util.Size;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;

import com.device.idea.demo.R;
import com.device.idea.demo.constant.Constant;
import com.device.idea.demo.util.LogUtil;
import com.device.idea.demo.util.MethodUtil;
import com.device.idea.demo.view.widget.DrawToolbar;
import com.device.idea.whiteboard.WhiteboardServiceController;
import com.device.idea.whiteboard.callback.AnnotationCallback;
import com.device.idea.whiteboard.callback.Callback;
import com.device.idea.whiteboard.callback.IWhiteboardEventHandler;
import com.device.idea.whiteboard.model.AppInfo;
import com.device.idea.whiteboard.model.ErrorCode;
import com.device.idea.whiteboard.model.StopStatus;
import com.device.idea.whiteboard.model.WhiteBoardBackgroundColor;
import com.device.idea.whiteboard.model.WhiteBoardEraser;
import com.device.idea.whiteboard.model.WhiteBoardEraserShape;
import com.device.idea.whiteboard.model.WhiteBoardEraserType;
import com.device.idea.whiteboard.model.WhiteBoardFeature;
import com.device.idea.whiteboard.model.WhiteBoardFileInfo;
import com.device.idea.whiteboard.model.WhiteBoardPen;
import com.device.idea.whiteboard.model.WhiteBoardPenStyle;
import com.device.idea.whiteboard.model.WhiteBoardQrcodeStyle;
import com.device.idea.whiteboard.model.WhiteBoardSaveStatus;
import com.device.idea.whiteboard.model.WhiteBoardSelector;
import com.device.idea.whiteboard.model.WhiteBoardTouchMode;
import com.device.idea.whiteboard.model.WhiteBoardTouchStyle;
import com.device.idea.whiteboard.model.parser.LayoutInfo;
import com.device.idea.whiteboard.view.RenderView;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * WhiteBoardActivity
 *
 * @since 2021-08-25
 */
public class WhiteBoardActivity extends AppCompatActivity
    implements View.OnClickListener, DrawToolbar.ClickCallback, IWhiteboardEventHandler {
    private static final String TAG = WhiteBoardActivity.class.getSimpleName();

    private static final String ACTION_ANNOTATION = "com.device.action.WHITEBOARD_ANNOTATION";

    private static final String ACTION_CONFERENCE_SEND = "com.device.action.WHITEBOARD_SEND";

    private static final String EXTRA_HANDLE = "extra_handle";

    private FrameLayout mContainer;

    private WhiteboardServiceController mController;

    private DrawToolbar mDrawToolbar;

    private int mCurrentPenType = WhiteBoardPenStyle.NORMAL_PEN.getValue();

    private WhiteBoardPen[] mWhiteBoardPens;

    private int mCurrentBoardId;

    private int mCurrentPageNum = Constant.DEFAULT_CURRENT_PAGE_NUM;

    private HashMap<Integer, Boolean> mIsCanUndoMaps = new HashMap<Integer, Boolean>();

    private HashMap<Integer, Boolean> mIsCanRedoMaps = new HashMap<Integer, Boolean>();

    private volatile boolean isSharingBoard = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        LogUtil.info(TAG, "onCreate");
        setContentView(R.layout.activity_white_board_4k);

        // 在xml里面设置了父布局，获取该父布局
        mContainer = findViewById(R.id.activity_main_container);
        mDrawToolbar = findViewById(R.id.wb_drawToolbar);
        if (mContainer == null || mDrawToolbar == null) {
            LogUtil.error(TAG, (mContainer == null ? "mContainer is null" : "")
                + (mDrawToolbar == null ? "mDrawToolbar is null" : ""));
            return;
        }

        initWhiteboardSetting();
        initController();
        int boardId = mController.newBoard();
        if (boardId == ErrorCode.FAIL) {
            LogUtil.error(TAG, "newBoard fail");
            return;
        }
        mCurrentBoardId = boardId;
        mController.setLimitPage(Constant.MAX_PAGE_COUNT);
        mController.setCurrentBoard(boardId);
        mController.setCurrentPage(mCurrentPageNum);
        mController.setPageBackground(Constant.CANVAS_BACKGROUND_COLOR_BLACK_RGBA);
        handleIntent(getIntent(), false);
        initDrawToolBar();
        initStyle();

        RenderView renderView = mController.getRenderView();
        if (renderView == null) {
            LogUtil.error(TAG, "renderView is null");
            return;
        }
        FrameLayout.LayoutParams params =
            new FrameLayout.LayoutParams(Constant.DEFAULT_SCREEN_WIDTH, Constant.DEFAULT_SCREEN_HEIGHT);
        renderView.setLayoutParams(params);
        mContainer.addView(renderView);

        // 需要文件读写权限
        verifyStoragePermissions(this);
    }

    private void initDrawToolBar() {
        mDrawToolbar.updateCheckedColorView(Constant.PICKER_COLORS[Constant.PEN_COLORS_INDEX_WHITE]);
        mDrawToolbar.updateCheckedTouchMode(WhiteBoardTouchMode.TOUCH_MODE_PEN.getValue());
        mDrawToolbar.setOnClickListener(this);
        mDrawToolbar.setToolbarClickListener(this);
        mDrawToolbar.updateIndicatorView(mCurrentPageNum, mController.getPageCounts());
        mDrawToolbar.initDrawableSize(mController.isCanvasLock());
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        LogUtil.info(TAG, "onNewIntent");
        handleIntent(intent, true);
        if (mDrawToolbar != null) {
            mDrawToolbar.updateIndicatorView(mCurrentPageNum, mController.getPageCounts());
        }
    }

    private void handleIntent(Intent intent, boolean isNeedNewPage) {
        if (intent == null) {
            return;
        }
        ComponentName componentName = getComponentName();
        String handle = "";
        if (intent.hasExtra(EXTRA_HANDLE)) {
            handle = intent.getStringExtra(EXTRA_HANDLE);
            LogUtil.info(TAG, "handle=" + handle);
        }
        if (handle == null || "".equals(handle)) {
            return;
        }
        mController.setWindowOpenStatus(componentName, handle);
        if (ACTION_CONFERENCE_SEND.equals(intent.getAction())) {
            LogUtil.info(TAG, "handle ACTION_CONFERENCE_SEND");
            startShareBoard();
        } else if (ACTION_ANNOTATION.equals(intent.getAction())) {
            LogUtil.info(TAG, "handle ACTION_ANNOTATION,isNeedNewPage=" + isNeedNewPage);
            createNewPage(isNeedNewPage);
            startAnnotation();
        } else if (Intent.ACTION_VIEW.equals(intent.getAction())) {
            LogUtil.info(TAG, "handle ACTION_VIEW");
            copyForImportBoard(intent.getData());
        } else {
            Log.e(TAG, "handleIntent unSupport action=" + intent.getAction());
        }
    }

    private void createNewPage(boolean isNeedNewPage) {
        if (isNeedNewPage) {
            mController.newPage();
            mCurrentPageNum = mController.getPageCounts();
            mController.setCurrentPage(mCurrentPageNum);
        }
    }

    private void copyForImportBoard(Uri uri) {
        LogUtil.info(TAG, "copyForImportBoard");
        String loadFilePath = MethodUtil.getFileFromFileProvider(this, uri);
        if (TextUtils.isEmpty(loadFilePath)) {
            LogUtil.error(TAG, "get file path error");
        } else {
            clickOpen(loadFilePath);
        }
    }

    private void startShareBoard() {
        mController.startShareBoard(mCurrentBoardId, new Callback<Void>() {
            @Override
            public void onSuccess(Void aVoid) {
                LogUtil.info(TAG, "startShareBoard onSuccess");
                isSharingBoard = true;
            }

            @Override
            public void onFailed(int errCode, String errMsg) {
                LogUtil.info(TAG, "startShareBoard onFailed" + ERR_CODE_KEY + errCode + ERR_MSG_KEY + errMsg);
            }
        });
    }

    private void startAnnotation() {
        mController.startAnnotation(new AnnotationCallback() {
            @Override
            public void onAnnotationStarted(int boardId) {
                LogUtil.info(TAG, "startAnnotation onAnnotationStarted" + BOARD_ID_KEY + boardId);
            }

            @Override
            public void onCaptureFinished() {
                int pageCounts = mController.getPageCounts();
                LogUtil.info(TAG, "startAnnotation onCaptureFinished pageCounts=" + pageCounts);
            }

            @Override
            public void onFailed(int errCode, String errMsg) {
                LogUtil.info(TAG, "startAnnotation onFailed" + ERR_CODE_KEY + errCode + ERR_MSG_KEY + errMsg);
            }
        });
    }

    // 然后通过一个函数来申请
    private void verifyStoragePermissions(Activity activity) {
        // 检测是否有写的权限 /sdcard/thumbnail/
        int permission = ActivityCompat.checkSelfPermission(activity, "android.permission.WRITE_EXTERNAL_STORAGE");
        if (permission != PackageManager.PERMISSION_GRANTED) {
            // 没有写的权限，去申请写的权限，会弹出对话框
            ActivityCompat.requestPermissions(activity,
                new String[] {"android.permission.READ_EXTERNAL_STORAGE", "android.permission.WRITE_EXTERNAL_STORAGE"},
                1);
        }
    }

    private void initController() {
        String filePath = getFilesDir().getPath();
        AppInfo appInfo = new AppInfo(getPackageName(), filePath);
        mController = WhiteboardServiceController.create(this, appInfo, this);
    }

    private void setPen(int type, int color) {
        if (mController == null) {
            return;
        }
        WhiteBoardPen pen = mWhiteBoardPens[type];
        pen.setType(WhiteBoardPenStyle.getEnum(type));
        pen.setColor(color);
        mWhiteBoardPens[type] = pen;
        mDrawToolbar.updateCheckedColorView(color);
        mDrawToolbar.updateCheckedTouchMode(WhiteBoardTouchMode.TOUCH_MODE_PEN.getValue());
        mDrawToolbar.checkPenTypeItem(type, getIndexByColor(color));
        mController.setTouchMode(WhiteBoardTouchMode.TOUCH_MODE_PEN);
        mController.setPen(pen);
    }

    private int getIndexByColor(int color) {
        for (int i = 0; i < Constant.PICKER_COLORS.length; i++) {
            if (color == Constant.PICKER_COLORS[i]) {
                return i;
            }
        }
        return 0;
    }

    private void initStyle() {
        mController.setEraserStyle(new WhiteBoardEraser[] {
            new WhiteBoardEraser(Constant.ERASE_COLOR, WhiteBoardEraserType.NORMAL_SIZE, WhiteBoardEraserShape.CIRCLE,
                Constant.NORMAL_CIRCLE_ERASER_WIDTH, Constant.ERASE_COLOR, Constant.ERASER_BORDER_WIDTH),
            new WhiteBoardEraser(Constant.ERASE_COLOR, WhiteBoardEraserType.MEDIUM_SIZE,
                WhiteBoardEraserShape.RECTANGLE, Constant.MIDDLE_RECTANGLE_ERASER_WIDTH, Constant.ERASE_COLOR,
                Constant.ERASER_BORDER_WIDTH),
            new WhiteBoardEraser(Constant.ERASE_COLOR, WhiteBoardEraserType.LARGE_SIZE, WhiteBoardEraserShape.RECTANGLE,
                Constant.LARGE_RECTANGLE_ERASER_WIDTH, Constant.ERASE_COLOR, Constant.ERASER_BORDER_WIDTH)});

        WhiteBoardSelector selector = new WhiteBoardSelector();
        selector.setLineColor(Constant.SELECTOR_LINE_COLOR);
        selector.setLineWidth(Constant.SELECTOR_LINE_WIDTH);
        selector.setOutlineColor(Constant.SELECTOR_OUTLINE_COLOR);
        selector.setOutlineWidth(Constant.SELECTOR_OUTLINE_WIDTH);
        selector.setBorderColor(Constant.SELECTOR_BORDER_COLOR);
        selector.setConnectCornerLineWidth(Constant.SELECTOR_CONNECT_CORNER_LINE_WIDTH);
        selector.setCornerWidth(Constant.SELECTOR_CORNER_WIDTH);
        mController.setSelectorStyle(selector);

        WhiteBoardTouchStyle touchStyle = new WhiteBoardTouchStyle();
        mController.setTouchStyle(touchStyle);

        setPen(WhiteBoardPenStyle.NORMAL_PEN.getValue(), Constant.DEFAULT_PEN_COLOR);
    }

    @Override
    public void onClick(View view) {
        if (mController == null) {
            return;
        }
        int id = view.getId();
        if (handlePageManager(id)) {
            return;
        }
        if (handleSelectPen(view)) {
            return;
        }
        handleClick(view, id);
    }

    private void handleClick(View view, int id) {
        switch (id) {
            case R.id.wbui_toolbar_eraser:
                mController.setTouchMode(WhiteBoardTouchMode.TOUCH_MODE_ERASER);
                if (mDrawToolbar != null) {
                    mDrawToolbar.showEraserPopWindow(view);
                }
                break;

            case R.id.wbui_toolbar_save:
                clickSave();
                break;

            case R.id.wbui_toolbar_more:
                mDrawToolbar.showMore(view, this);
                break;

            case R.id.wbui_toolbar_open:
                String filePath = getFilesDir().getPath() + File.separator + "1.cwb";
                clickOpen(filePath);
                break;

            case R.id.wbui_toolbar_select:
                mController.setTouchMode(WhiteBoardTouchMode.TOUCH_MODE_SELECT);
                mDrawToolbar.updateCheckedTouchMode(WhiteBoardTouchMode.TOUCH_MODE_SELECT.getValue());
                break;

            case R.id.wbui_toolbar_previous: // 上一步
                mController.undo();
                break;

            case R.id.wbui_toolbar_posterior:
                mController.redo();
                break;

            case R.id.wbui_toolbar_canvasMode:
                clickCanvasLock();
                break;

            case R.id.wbui_toolbar_setting:
                if (mDrawToolbar != null) {
                    mDrawToolbar.showSettingPickerPopWindow(view);
                }
                break;

            case R.id.wbui_toolbar_exit:
                finish();
                break;
            default:
                LogUtil.error(TAG, "Unknown click listener!");
                break;
        }
    }

    private void clickCanvasLock() {
        boolean isCanvasLock = mController.isCanvasLock();
        mDrawToolbar.updateCanvasLockState(!isCanvasLock);
        mController.setCanvasLock(!isCanvasLock);
    }

    private void clickSave() {
        Log.i(TAG, "clickSave");
        String savePath = getFilesDir().getPath() + File.separator + "1.cwb";
        mController.saveBoard(savePath, new Callback<Void>() {
            @Override
            public void onSuccess(Void aVoid) {
                Log.i(TAG, "saveBoard onSuccess: ");
                runOnUiThread(
                    () -> Toast.makeText(WhiteBoardActivity.this, R.string.common_save_success, Toast.LENGTH_SHORT)
                        .show());
                mController.setSaveStatus(getComponentName(), new WhiteBoardSaveStatus(true));
            }

            @Override
            public void onFailed(int errCode, String errMsg) {
                Log.i(TAG, "saveBoard onFailed: ");
                runOnUiThread(
                    () -> Toast
                        .makeText(WhiteBoardActivity.this,
                            getResources().getString(R.string.common_save_failed) + errCode, Toast.LENGTH_SHORT)
                        .show());
            }
        });
    }

    private void clickOpen(String filePath) {
        Log.i(TAG, "clickOpen");
        mController.loadBoard(filePath, new Callback<Integer>() {
            @Override
            public void onSuccess(Integer boardId) {
                LogUtil.info(TAG, "onSuccess: " + boardId);
                updateBoardId(boardId);
                runOnUiThread(() -> Toast
                    .makeText(WhiteBoardActivity.this, R.string.common_load_board_success, Toast.LENGTH_SHORT)
                    .show());
            }

            @Override
            public void onFailed(int error, String msg) {
                runOnUiThread(() -> Toast
                    .makeText(WhiteBoardActivity.this,
                        getResources().getString(R.string.common_load_board_fail_title) + msg, Toast.LENGTH_SHORT)
                    .show());
            }
        });
    }

    private void updateBoardId(int boardId) {
        if (mController == null) {
            return;
        }
        mController.setCurrentBoard(boardId);
        mController.setCurrentPage(Constant.DEFAULT_LOAD_WHITEBOARD_FIRST_PAGE);
        mCurrentPageNum = Constant.DEFAULT_LOAD_WHITEBOARD_FIRST_PAGE;
        mCurrentBoardId = boardId;
        runOnUiThread(() -> mDrawToolbar.updateIndicatorView(mCurrentPageNum, mController.getPageCounts()));
    }

    /**
     * 响应页面管理点击事件
     *
     * @param viewId viewId
     * @return true/fales
     */
    private boolean handlePageManager(int viewId) {
        switch (viewId) {
            case R.id.wbui_toolbar_delete:
                clickDeleteDo();
                return true;
            case R.id.wbui_toolbar_last:
                clickPrePage();
                return true;
            case R.id.wbui_toolbar_next:
                clickNextPage();
                return true;
            case R.id.wbui_toolbar_add:
                clickAddPage();
                return true;
            case R.id.rearrange_to_pre:
                reArrange2Pre();
                return true;
            case R.id.rearrange_to_next:
                reArrange2Next();
                return true;
            default:
                return false;
        }
    }

    private void clickDeleteDo() {
        boolean isLastPage = mCurrentPageNum == mController.getPageCounts();
        mController.deletePage(mCurrentPageNum);
        if (mCurrentPageNum != 1 && isLastPage) {
            mCurrentPageNum--;
        }
        mController.setCurrentPage(mCurrentPageNum);
        mDrawToolbar.updateIndicatorView(mCurrentPageNum, mController.getPageCounts());
    }

    private void clickPrePage() {
        if (mCurrentPageNum > 1) {
            mController.prePage();
            mCurrentPageNum--;
            mDrawToolbar.updateIndicatorView(mCurrentPageNum, mController.getPageCounts());
        }
    }

    private void clickNextPage() {
        int counts = mController.getPageCounts();
        if (mCurrentPageNum < counts) {
            mController.nextPage();
            mCurrentPageNum++;
            mDrawToolbar.updateIndicatorView(mCurrentPageNum, counts);
        }
    }

    private void clickAddPage() {
        if (mController.getPageCounts() >= Constant.MAX_PAGE_COUNT) {
            Toast.makeText(this, getResources().getString(R.string.wb_page_max_error), Toast.LENGTH_SHORT).show();
        } else {
            int pageIndex = mController.newPage();
            if (pageIndex > 0) {
                mController.setCurrentPage(pageIndex);
                mCurrentPageNum = pageIndex;
                mDrawToolbar.updateIndicatorView(mCurrentPageNum, mController.getPageCounts());
            }
        }
    }

    private void reArrange2Pre() {
        if (mCurrentPageNum > 1) {
            mController.rearrangePages(mCurrentPageNum, --mCurrentPageNum);
            mDrawToolbar.updateIndicatorView(mCurrentPageNum, mController.getPageCounts());
        }
    }

    private void reArrange2Next() {
        int counts = mController.getPageCounts();
        if (mCurrentPageNum < counts) {
            mController.rearrangePages(mCurrentPageNum, ++mCurrentPageNum);
            mDrawToolbar.updateIndicatorView(mCurrentPageNum, counts);
        }
    }

    /**
     * 响应笔选择点击事件
     *
     * @param view view
     * @return true/fales
     */
    private boolean handleSelectPen(View view) {
        switch (view.getId()) {
            case R.id.wbui_toolbar_penBlack:
                if (mDrawToolbar.getCurrentCanvasBgColor() == Constant.CANVAS_BACKGROUND_COLOR_WHITE_RGBA) {
                    setPen(mCurrentPenType, Constant.PICKER_COLORS[Constant.PEN_COLORS_INDEX_BLACK]);
                } else {
                    setPen(mCurrentPenType, Constant.PICKER_COLORS[Constant.PEN_COLORS_INDEX_WHITE]);
                }
                return true;
            case R.id.wbui_toolbar_penRed:
                setPen(mCurrentPenType, Constant.PICKER_COLORS[Constant.PEN_COLORS_INDEX_RED]);
                return true;
            case R.id.wbui_toolbar_penGreen:
                setPen(mCurrentPenType, Constant.PICKER_COLORS[Constant.PEN_COLORS_INDEX_GREEN]);
                return true;
            case R.id.wbui_toolbar_pencil:
                mDrawToolbar.showPens(view, mWhiteBoardPens);
                mController.setTouchMode(WhiteBoardTouchMode.TOUCH_MODE_PEN);
                return true;
            default:
                return false;
        }
    }

    /**
     * 初始化设置数据，可以从M获取持久化数据
     */
    private void initWhiteboardSetting() {
        mWhiteBoardPens = new WhiteBoardPen[Constant.DEFAULT_PEN_MAX_COUNT];
        int penWidth = getResources().getDimensionPixelSize(R.dimen.wb_pen_pencil_stroke_width);
        for (int idx = 0; idx < mWhiteBoardPens.length; idx++) {
            mWhiteBoardPens[idx] =
                new WhiteBoardPen(Constant.DEFAULT_PEN_COLOR, penWidth, WhiteBoardPenStyle.getEnum(idx));
        }
    }

    private void releaseController() {
        if (mController != null) {
            LogUtil.info(TAG, "releaseController");
            stopShareBoard();
            mController.deleteBoard(mCurrentBoardId);
            mController.setWindowCloseStatus(getComponentName());
            mController.destroy();
            mController = null;
        }
    }

    private void stopShareBoard() {
        LogUtil.info(TAG, "stopShareBoard,isSharingBoard=" + isSharingBoard);
        if (isSharingBoard) {
            mController.setBoardWindowsStatus(mCurrentBoardId, StopStatus.CLOSE_WHITEBOARD_WHEN_STOPSHARE);
            mController.stopShareBoard(mCurrentBoardId, new Callback<Void>() {
                @Override
                public void onSuccess(Void aVoid) {
                    LogUtil.info(TAG, "stopShareBoard success.");
                }

                @Override
                public void onFailed(int errCode, String errMsg) {
                    LogUtil.info(TAG, "stopShareBoard onFailed" + ERR_CODE_KEY + errCode + ERR_MSG_KEY + errMsg);
                }
            });
            isSharingBoard = false;
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        LogUtil.info(TAG, "onDestroy");
        clearContainer();
        releaseController();
        clearUndoMaps();
        clearRedoMaps();
    }

    private void clearRedoMaps() {
        if (mIsCanRedoMaps != null) {
            mIsCanRedoMaps.clear();
            mIsCanRedoMaps = null;
        }
    }

    private void clearUndoMaps() {
        if (mIsCanUndoMaps != null) {
            mIsCanUndoMaps.clear();
            mIsCanUndoMaps = null;
        }
    }

    private void clearContainer() {
        if (mContainer != null) {
            mContainer.removeAllViews();
        }
    }

    @Override
    public void onSelectPen(int color, int type) {
        mCurrentPenType = type;
        setPen(type, color);
    }

    @Override
    public void onClearScreen() {
        if (mController != null) {
            mController.cleanScreen();
        }
    }

    @Override
    public void onSelectBackgroundColor(int color) {
        if (mController == null) {
            return;
        }
        mController.setPageBackground(color);
        if (mDrawToolbar != null) {
            WhiteBoardPen currentPen = mWhiteBoardPens[mCurrentPenType];
            int reversesColor;
            if (color == Constant.CANVAS_BACKGROUND_COLOR_WHITE_RGBA) {
                reversesColor = Constant.PICKER_COLORS[Constant.PEN_COLORS_INDEX_BLACK];
            } else {
                reversesColor = Constant.PICKER_COLORS[Constant.PEN_COLORS_INDEX_WHITE];
            }

            for (WhiteBoardPen whiteBoardPen : mWhiteBoardPens) {
                if (whiteBoardPen.getColor() == Constant.PICKER_COLORS[Constant.PEN_COLORS_INDEX_BLACK]
                    || whiteBoardPen.getColor() == Constant.PICKER_COLORS[Constant.PEN_COLORS_INDEX_WHITE]) {
                    whiteBoardPen.setColor(reversesColor);
                }
            }

            mDrawToolbar.checkPenTypeItem(mCurrentPenType, getIndexByColor(currentPen.getColor()));
            mController.setPen(currentPen);
        }
    }

    /**
     * 新建白板
     *
     * @param view 白板view
     */
    public void newBoard(View view) {
        int boardId = mController.newBoard();
        LogUtil.info(TAG, "newBoard" + BOARD_ID_KEY + boardId);
    }

    /**
     * 设置最大页
     *
     * @param view 白板view
     */
    public void setLimitPageDemo(View view) {
    }

    /**
     * 撤销
     *
     * @param view 白板view
     */
    public void undoDemo(View view) {
        mController.undo();
    }

    /**
     * 前一页
     *
     * @param view 白板view
     */
    public void prePage(View view) {
        mController.prePage();
    }

    /**
     * 下一页
     *
     * @param view 白板view
     */
    public void nextPage(View view) {
        mController.nextPage();
    }

    /**
     * 销毁controller实例
     *
     * @param view 白板view
     */
    public void destroy(View view) {
        mController.destroy();
    }

    /**
     * 保存为图片
     *
     * @param view 白板view
     */
    public void savePageAsImage(View view) {
        mController.savePageAsImage(1, "sdcard/", new Size(IMAGE_SAVE_WIDTH, IMAGE_SAVE_HEIGHT));
    }

    /**
     * 保存board
     *
     * @param view 白板view
     */
    public void saveBoard(View view) {
        mController.saveBoard("WhiteBoard.txt", new Callback<Void>() {
            @Override
            public void onSuccess(Void aVoid) {
                LogUtil.info(TAG, "saveBoard onSuccess");
            }

            @Override
            public void onFailed(int errorCode, String errorMsg) {
                LogUtil.error(TAG, "saveBoard onFailed" + ERR_CODE_KEY + errorCode + ERR_MSG_KEY + errorMsg);
            }
        });
    }

    /**
     * 加载board
     *
     * @param view 白板view
     */
    public void loadBoard(View view) {
        mController.loadBoard("WhiteBoard.txt", new Callback<Integer>() {
            @Override
            public void onSuccess(Integer integer) {
                RenderView renderView = mController.getRenderView();
                LogUtil.debug(TAG, "renderView ====" + renderView);
            }

            @Override
            public void onFailed(int errorCode, String errorMsg) {
                LogUtil.error(TAG, "saveBoard onFailed" + ERR_CODE_KEY + errorCode + ERR_MSG_KEY + errorMsg);
            }
        });
    }

    /**
     * 获取controller实例
     *
     * @return controller实例
     */
    public WhiteboardServiceController getController() {
        return mController;
    }

    /**
     * 获取当前页编号
     *
     * @return 获取当前页编号
     */
    public int getCurrentPageNum() {
        return mCurrentPageNum;
    }

    /**
     * 获取当前页白板编号
     *
     * @return 前页白板编号
     */
    public int getCurrentBoardId() {
        return mCurrentBoardId;
    }

    // 设置工具栏位置
    private void setToolLocation() {
        Rect rect = new Rect(0, Constant.DEFAULT_SCREEN_HEIGHT - mDrawToolbar.getLayoutParams().height,
            Constant.DEFAULT_SCREEN_WIDTH, Constant.DEFAULT_SCREEN_HEIGHT);
        RenderView renderView = mController.getRenderView();
        List<Rect> rectList = new ArrayList<>();
        rectList.add(rect);
        renderView.setDisabledRects(rectList);
    }

    @Override
    protected void onResume() {
        super.onResume();
        mDrawToolbar.updateIndicatorView(mCurrentPageNum, mController.getPageCounts());
        setToolLocation();
        LogUtil.info(TAG, "onResume");
    }

    @Override
    protected void onPause() {
        super.onPause();
        LogUtil.info(TAG, "onPause");
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
        @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

    @Override
    public void onCanUndoNotify(boolean isEnabled, int boardId, int pageNumber) {
        LogUtil.info(TAG,
            "onCanUndoNotify isEnabled=" + isEnabled + BOARD_ID_KEY + boardId + PAGE_NUMBER_KEY + pageNumber);
        runOnUiThread(() -> mDrawToolbar.updatePreView(isEnabled));
    }

    @Override
    public void onCanRedoNotify(boolean isEnabled, int boardId, int pageNumber) {
        LogUtil.info(TAG,
            "onCanRedoNotify isEnabled=" + isEnabled + BOARD_ID_KEY + boardId + PAGE_NUMBER_KEY + pageNumber);
        runOnUiThread(() -> mDrawToolbar.updatePostView(isEnabled));
    }

    @Override
    public void onCanvasScaleChangedNotify(int scale, int boardId, int pageNumber) {
        LogUtil.info(TAG,
            "onCanvasScaleChangedNotify scale=" + scale + BOARD_ID_KEY + boardId + PAGE_NUMBER_KEY + pageNumber);
    }

    @Override
    public void onBoardIdChangedNotify(int boardId) {
        LogUtil.info(TAG, "onBoardIdChangedNotify" + BOARD_ID_KEY + boardId);
    }

    @Override
    public void onPageNumberChangedNotify(int pageNumber, int boardId) {
        LogUtil.info(TAG, "onPageNumberChangedNotify pageNumber=" + pageNumber + BOARD_ID_KEY + boardId);
    }

    @Override
    public void onPageChangedNotify(int boardId, int fromPageNumber, int toPageNumber) {
        LogUtil.info(TAG, "onPageChangedNotify" + BOARD_ID_KEY + boardId + ",fromPageNumber=" + fromPageNumber
            + ",toPageNumber=" + toPageNumber);
    }

    @Override
    public void onPageDeletedNotify(int pageNumber, int boardId) {
        LogUtil.info(TAG, "onPageDeletedNotify pageNumber=" + pageNumber + BOARD_ID_KEY + boardId);
    }

    @Override
    public void onPageCreatedNotify(int pageNumber, int boardId) {
        LogUtil.info(TAG, "onPageCreatedNotify pageNumber=" + pageNumber + BOARD_ID_KEY + boardId);
    }

    @Override
    public void onBoardDeletedNotify(int boardId) {
        LogUtil.info(TAG, "onBoardDeletedNotify" + BOARD_ID_KEY + boardId);
    }

    @Override
    public void onError(int errorCode, String errorMsg) {
        LogUtil.error(TAG, "onError errorCode=" + errorCode + ",errorMsg=" + errorMsg);
    }

    @Override
    public void onCanvasAnnotChangedNotify(int boardId, int pageNumber) {
        LogUtil.info(TAG, "onCanvasAnnotChangedNotify" + BOARD_ID_KEY + boardId + PAGE_NUMBER_KEY + pageNumber);
    }

    @Override
    public void onSelectNotify(int boardId, int pageNumber, Point point, Size size, boolean isSelectContentChange) {
        LogUtil.info(TAG, "onSelectNotify" + BOARD_ID_KEY + boardId + PAGE_NUMBER_KEY + pageNumber + ",left top point="
            + point + ",size=" + size + ",isSelectContentChange=" + isSelectContentChange);
    }

    @Override
    public void onSharedTypeChangedNotify(WhiteBoardQrcodeStyle qrShareType) {
        LogUtil.info(TAG, "onSharedTypeChangedNotify qrShareType=" + qrShareType);
    }

    @Override
    public void onEnabledSharedTypeChangedNotify(List<WhiteBoardQrcodeStyle> qrShareTypeList) {
        LogUtil.info(TAG, "onEnabledSharedTypeChangedNotify qrShareTypeList=" + qrShareTypeList);
    }

    @Override
    public void onSharedWbFileListNotify(List<WhiteBoardFileInfo> fileList, String userName) {
        LogUtil.info(TAG, "onSharedWbFileListNotify fileList=" + fileList + ",userName=" + userName);
    }

    @Override
    public void onBackgroundChangedNotify(WhiteBoardBackgroundColor backgroundColor) {
        LogUtil.info(TAG, "onBackgroundChangedNotify backgroundColor=" + backgroundColor);
    }

    @Override
    public void onPagesRearrangedNotify(int fromPageNumber, int toPageNumber) {
        LogUtil.info(TAG, "onPagesRearrangedNotify fromPageNumber=" + fromPageNumber + ",toPageNumber=" + toPageNumber);
    }

    @Override
    public void onFileUnsavedNotify(String unsavedFileName) {
        LogUtil.info(TAG, "onFileUnsavedNotify unsavedFileName=" + unsavedFileName);
    }

    @Override
    public void onLayoutChangedNotify(LayoutInfo layoutInfo) {
        LogUtil.info(TAG, "onLayoutChangedNotify layoutInfo=" + layoutInfo);
    }

    @Override
    public void onDoublePenChangedNotify(int boardId, int pageNumber, boolean isThinPen) {
        LogUtil.info(TAG, "onDoublePenChangedNotify" + BOARD_ID_KEY + boardId + PAGE_NUMBER_KEY + pageNumber
            + ",isThinPen=" + isThinPen);
    }

    @Override
    public void onCapturePPTPageNotify(int pageNumber) {
        LogUtil.info(TAG, "onCapturePPTPageNotify pageNumber=" + pageNumber);
    }

    @Override
    public void onSwitchPPTPageNotify(boolean isPageDown) {
        LogUtil.info(TAG, "onSwitchPPTPageNotify isPageDown=" + isPageDown);
    }

    @Override
    public void onContentNotify(int length, byte[] content) {
        LogUtil.info(TAG, "onContentNotify length=" + length);
    }

    @Override
    public void onCanvasDragToEdgeNotify(int boardId) {
        LogUtil.info(TAG, "onCanvasDragToEdgeNotify" + BOARD_ID_KEY + boardId);
    }

    @Override
    public void onCanvasDragNotify(int boardId) {
        LogUtil.info(TAG, "onCanvasDragNotify" + BOARD_ID_KEY + boardId);
    }

    @Override
    public void onShareBoardStopNotify(ComponentName componentName) {
        LogUtil.info(TAG, "onShareBoardStopNotify componentName=" + componentName);
        isSharingBoard = false;
    }

    @Override
    public boolean onCloseBoardNotify(ComponentName componentName) {
        LogUtil.info(TAG, "onCloseBoardNotify componentName=" + componentName);
        mController.setSaveStatus(componentName, new WhiteBoardSaveStatus(true));
        finish();
        return true;
    }

    @Override
    public boolean isWhiteboardChange(ComponentName componentName) {
        LogUtil.info(TAG, "isWhiteboardChange componentName=" + componentName);
        return false;
    }

    @Override
    public void onStatusChangeNotify(int boardId, int status) {
        LogUtil.info(TAG, "onStatusChangeNotify" + BOARD_ID_KEY + boardId + ",status=" + status);
    }

    @Override
    public void onCloseWindowNotify(ComponentName componentName) {
        LogUtil.info(TAG, "onCloseWindowNotify componentName=" + componentName);
    }

    @Override
    public void onEnabledFeaturesChangedNotify(int boardId, List<WhiteBoardFeature> list) {
        LogUtil.info(TAG, "onEnabledFeaturesChangedNotify" + BOARD_ID_KEY + boardId + ",list=" + list);
    }

    @Override
    public void onPointerCaptureChanged(boolean hasCapture) {
        LogUtil.info(TAG, "onPointerCaptureChanged hasCapture=" + hasCapture);
        super.onPointerCaptureChanged(hasCapture);
    }
}